# -*- coding: utf-8 -*-
# @Time    : 2024/6/28 10:37
# @Author  : yujiahao
# @File    : 01_numpy_ndarray_obj.py
# @description:NumPy ndarray对象


import numpy as np


#  todo 1、NumPy ndarray对象
def numpy_create_array():
    """
    NumPy ndarray 对象简介

    NumPy 定义了一个 n 维数组对象，简称 ndarray 对象，它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块，您可以使用索引或切片的方式获取数组中的每个元素。

    ndarray 对象有一个 dtype 属性，该属性用来描述元素的数据类型。

    ndarray 对象采用了数组的索引机制，将数组中的每个元素映射到内存块上，并且按照一定的布局对内存块进行排列，常用的布局方式有两种，即按行或者按列。

    创建 ndarray 对象
    -----------------

    通过 NumPy 的内置函数 array() 可以创建 ndarray 对象，其语法格式如下：
        numpy.array(object, dtype = None, copy = True, order = None, ndmin = 0)

    下面表格对其参数做了说明：

    参数说明
    ---------

    序号    参数      描述说明
    -----   -------   ---------------------------------
    1       object    表示一个数组序列。
    2       dtype     可选参数，通过它可以更改数组的数据类型。
    3       copy      可选参数，表示数组能否被复制，默认是 True。
    4       order     以哪种内存布局创建数组，有 3 个可选值，分别是 C(行序列)/F(列序列)/A(默认)。
    5       ndmin     用于指定数组的维度。

    """

    # todo 1.1、使用列表构建一维数组
    a = np.array([1, 2, 3])
    print(a)

    print('查看ndarray数组类型', type(a))

    # todo 1.2、创建多维数组：
    b = np.array([[1, 2, 3], [4, 5, 6]])
    print(b)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 如果要改变数组元素的数据类型，可以使用通过设置 dtype
    # c = np.array([2, 4, 6, 8], dtype="数据类型名称")

    # todo 1.3、numpy.empty()

    '''
        numpy.empty() 创建未初始化的数组，可以指定创建数组的形状（shape）和数据类型（dtype），语法格式如下：
        numpy.empty(shape, dtype = float, order = 'C')

        它接受以下参数：
            shape：指定数组的形状；
            dtype：数组元素的数据类型，默认值是值 float；
            order：指数组元素在计算机内存中的储存顺序，默认顺序是“C”(行优先顺序)。
            
        numpy.empty() 返回的数组带有随机值，但这些数值并没有实际意义。切记 empty 并非创建空数组。
        如果总是看到 np.empty 创建的数组初始化为零，这可能是特定环境或实现的行为，但不应依赖这种行为。
    '''

    print('创建一个三行两列的空数组：', np.empty((3, 2), dtype=int))

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 1.4、numpy.zeros()

    """
    该函数用来创建元素均为 0 的数组，同时还可以指定数组的形状，语法格式如下：
    numpy.zeros(shape, dtype=float, order='C')

    参数说明
    参数名称    说明描述
    shape      指定数组的形状大小。
    dtype      可选项，数组的数据类型，默认为 float。
    order      'C' 代表以行顺序存储，'F' 则表示以列顺序存储。
    """
    # 默认数据类型为浮点数
    a = np.zeros(6)
    b = np.zeros(6, dtype="complex64")
    print('创建一个元素均为0的空数组\n', b)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 1.5、numpy.ones()
    # 返回指定形状大小与数据类型的新数组，并且新数组中每项元素均用 1 填充，语法格式如下：
    # numpy.ones(shape, dtype = None, order = 'C')

    print('创建一个均为1的数组\n', np.ones((4, 5), dtype=int))

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')
    print('''下面介绍如何使用 Python 列表、流对象、可迭代对象来创建一个 NumPy 数组。''')
    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')
    # todo 1.6、numpy.asarray()
    '''
    asarray() 与 array() 类似，但是它比 array() 更为简单。asarray() 能够将一个 Python 序列转化为 ndarray 对象，语法格式如下：
    
        numpy.asarray（sequence，dtype = None ，order = None ）

    它接受下列参数：
        sequence：接受一个 Python 序列，可以是列表或者元组；
        dtype：可选参数，数组的数据类型；
        order：数组内存布局样式，可以设置为 C 或者 F，默认是 C。
    '''

    # 使用元组创建 numpy 数组：
    l = (1, 2, 3, 4, 5, 6, 7)
    a = np.asarray(l)
    print(type(a))
    print(a)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # numpy.frombuffer()
    '''
        表示使用指定的缓冲区创建数组。下面给出了该函数的语法格式：
            numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
        
        它的参数说明如下所示：
            buffer：将任意对象转换为流的形式读入缓冲区；
            dtype：返回数组的数据类型，默认是 float32；
            count：要读取的数据数量，默认为 -1 表示读取所有数据；
            offset：读取数据的起始位置，默认为 0。
    '''

    # 字节串类型
    l = b'hello world'
    print(type(l))
    a = np.frombuffer(l, dtype="S1")
    print('用指定的缓冲区创建数组', a)
    print(type(a))

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # numpy.fromiter()

    """
    该方法可以把迭代对象转换为 ndarray 数组，其返回值是一个一维数组。
    语法格式如下：
    numpy.fromiter(iterable, dtype, count=-1)

    参数说明如下：

    参数名称    描述说明
    iterable   可迭代对象。
    dtype      返回数组的数据类型。
    count      读取的数据数量，默认为 -1，读取所有数据。
    """

    # 使用内置 range() 函数创建列表对象，然后使用迭代器创建 ndarray 对象，

    # 使用 range 函数创建列表对象
    list = range(6)
    # 生成可迭代对象i
    i = iter(list)
    # 使用i迭代器，通过fromiter方法创建ndarray
    array = np.fromiter(i, dtype=float)
    print(array)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 1.7、 NumPy创建区间数组

    '''所谓区间数组，是指数组元素的取值位于某个范围内，并且数组元素之间可能会呈现某种规律，比如等比数列、递增、递减等。'''

    # 1. numpy.arange()

    """
    在 NumPy 中，您可以使用 arange() 来创建给定数值范围的数组，语法格式如下：
    numpy.arange(start, stop, step, dtype)

    参数说明如下：

    参数名称    参数说明
    start      起始值，默认是 0。
    stop       终止值，注意生成的数组元素值不包含终止值。
    step       步长，默认为 1。
    dtype      可选参数，指定 ndarray 数组的数据类型。
    """

    # 示例：创建一个从 0 到 10（不包含 10），步长为 2 的数组
    array_arange = np.arange(0, 10, 2)
    print('创建一个从 0 到 10（不包含 10），步长为 2 的数组：', array_arange)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 2. numpy.linspace()

    """
    表示在指定的数值区间内，返回均匀间隔的一维等差数组，默认均分 50 份，语法格式如下：
    np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

    参数说明如下：

    参数名称    参数说明
    start      代表数值区间的起始值；
    stop       代表数值区间的终止值；
    num        表示数值区间内要生成多少个均匀的样本。默认值为 50；
    endpoint   默认为 True，表示数列包含 stop 终止值，反之不包含；
    retstep    默认为 False，表示生成的数组中不显示公差项，若为 True 则显示；
    dtype      代表数组元素值的数据类型。
    """

    # 示例：创建一个从 0 到 10 的等差数组，均分 5 份
    array_linspace = np.linspace(0, 10, num=5, retstep=True)
    print('创建一个从 0 到 10 的等差数组，均分 5 份：', array_linspace)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 3. numpy.logspace

    """
    该函数同样返回一个 ndarray 数组，它用于创建等比数组，语法格式如下：
    np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
    
    参数详细说明如下：
    
    参数名称    说明描述
    start      序列的起始值：base**start。
    stop       序列的终止值：base**stop。
    num        数值范围区间内样本数量，默认为 50。
    endpoint   默认为 True，表示包含终止值；如果为 False，则不包含终止值。
    base       对数函数的 log 底数，默认为 10。
    dtype      可选参数，指定 ndarray 数组的数据类型。
    """

    # 示例 ：创建一个从 10^0 到 10^2 的等比数组，均分 5 份，不包含终止值
    array_logspace_no_endpoint = np.logspace(0, 2, num=5, endpoint=False)
    print('创建一个从 10^0 到 10^2 的等比数组，均分 5 份，不包含终止值：', array_logspace_no_endpoint)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 下面是 base = 2 的对数函数，示例如下：
    a = np.logspace(1, 10, num=10, base=2)
    print(a)


#  todo 2、 NumPy数据类型

def numpy_type():
    """
    NumPy 数据类型

    序号  数据类型   语言描述
    ----  --------   ------------------------------------------------------------
    1     bool_      布尔型数据类型（True 或者 False）
    2     int_       默认整数类型，类似于 C 语言中的 long，取值为 int32 或 int64
    3     intc       和 C 语言的 int 类型一样，一般是 int32 或 int 64
    4     intp       用于索引的整数类型（类似于 C 的 ssize_t，通常为 int32 或 int64）
    5     int8       代表与1字节相同的8位整数。值的范围是-128到127。
    6     int16      代表 2 字节（16位）的整数。范围是-32768至32767。
    7     int32      代表 4 字节（32位）整数。范围是-2147483648至2147483647。
    8     int64      表示 8 字节（64位）整数。范围是-9223372036854775808至9223372036854775807。
    9     uint8      代表1字节（8位）无符号整数。
    10    uint16     2 字节（16位）无符号整数。
    11    uint32     4 字节（32位）的无符号整数。
    12    uint64     8 字节（64位）的无符号整数。
    13    float_     float64 类型的简写。
    14    float16    半精度浮点数，包括：1 个符号位，5 个指数位，10个尾数位。
    15    float32    单精度浮点数，包括：1 个符号位，8 个指数位，23个尾数位。
    16    float64    双精度浮点数，包括：1 个符号位，11 个指数位，52个尾数位。
    17    complex_   复数类型，与 complex128 类型相同。
    18    complex64  表示实部和虚部共享 32 位的复数。
    19    complex128 表示实部和虚部共享 64 位的复数。
    20    str_       表示字符串类型
    21    string_    表示字节串类型

   数据类型对象（Data Type Object）又称 dtype 对象，主要用来描述数组元素的数据类型、大小以及字节顺序。同时，它也可以用来创建结构化数据。
   比如常见的 int64、float32 都是 dtype 对象的实例，其语法格式如下：

        np.dtype(object)


    NumPy 数据类型标识码

    字符  对应类型
    ----  -----------------------------
    b     代表布尔型
    i     带符号整型
    u     无符号整型
    f     浮点型
    c     复数浮点型
    m     时间间隔（timedelta）
    M     datetime（日期时间）
    O     Python对象
    S,a   字节串（S）与字符串（a）
    U     Unicode
    V     原始数据（void）


    结构化数组（structured array）在处理复杂数据结构时非常有用，尤其是在需要同时处理多种不同类型的数据时。
    以下是一些具体的应用场景和优势：

    应用场景：
        1. 数据分析与处理：
           - 在数据分析中，常常需要处理包含多种数据类型的表格数据。例如，一个包含姓名（字符）、年龄（整数）、工资（浮点数）的员工数据表。结构化数组可以方便地存储和处理这种数据。

        2. 科学计算与实验数据：
           - 科学实验中经常需要处理包含多个测量值的记录，例如时间、温度、压力等。结构化数组可以将这些不同类型的数据存储在一个数组中，便于统一管理和分析。

        3. 数据库操作：
           - 结构化数组可以用来模拟数据库表格的结构，方便从数据库中提取数据进行分析和处理。

        4. 数据交换与存储：
           - 在数据交换和存储时，结构化数组可以用来保存复杂的数据结构，并且可以方便地序列化和反序列化。

        优势：
        1. 内存效率：
           - 结构化数组在内存中是连续存储的，避免了 Python 原生数据结构（如列表和字典）带来的内存碎片问题，能够显著提高内存利用效率。

        2. 访问速度：
           - 由于数据是连续存储的，结构化数组可以利用 CPU 缓存，提高数据访问速度。NumPy 提供了高效的 C 语言实现，进一步提升了性能。

        3. 便捷的数据操作：
           - 结构化数组允许你使用字段名直接访问数据，类似于字典的操作方式，非常直观。同时，NumPy 提供了丰富的函数和方法来操作这些数组。

        4. 与其他工具兼容：
           - 结构化数组可以方便地与 Pandas、SciPy 等其他科学计算工具结合使用，增强数据处理能力。
    """

    # todo 2.1、数据类型对象

    print(np.dtype(np.int64))

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 2.2、使用数据类型标识码，创建一组结构化数据
    # 下面是一个更复杂的示例，展示了如何使用结构化数组来存储和操作包含多个字段的数据：
    # 定义一个包含多个字段的数据类型,说白了就是限制一下数据的存储空间，让其变得更优化一点
    dt = np.dtype([
        ('name', 'U10'),  # 字符串，最多10个字符
        ('age', 'i4'),  # 4字节整数
        ('salary', 'f8')  # 8字节浮点数
    ])

    # 创建一个包含多个记录的数组
    data = np.array([
        ('Alice', 25, 50000.0),
        ('Bob', 30, 60000.0),
        ('Charlie', 35, 70000.0)
    ], dtype=dt)

    # 打印整个数组
    print(data)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 访问所有记录的 'name' 字段
    print(data['name'])

    # 访问所有记录的 'age' 字段
    print(data['age'])

    # 访问所有记录的 'salary' 字段
    print(data['salary'])

    # 筛选出年龄大于30的记录
    filtered_data = data[data['age'] > 30]
    print(filtered_data)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 2.3、定义结构化数据
    '''
    通常情况下，结构化数据使用字段的形式来描述某个对象的特征。以下示例描述一位老师的姓名、年龄、工资的特征，该结构化数据其包含以下字段：
        str 字段：name
        int 字段：age
        float 字段：salary
    
    '''
    teacher = np.dtype([('name', 'S20'), ('age', 'i1'), ('salary', 'f4')])
    # 输出结构化数据teacher
    print(teacher)
    # 将其应用于ndarray对象
    b = np.array([('ycs', 32, 6357.50), ('jxe', 28, 6856.80)], dtype=teacher)
    print(b)


# todo 3、NumPy数组属性
def numpy_attribute():
    # 创建一个示例数组
    arr = np.array([[1, 2, 3], [4, 5, 6]])

    # todo 3.1、打印数组属性

    # 数组维度 (ndim): 数组的维度（轴）的数量。
    print("数组维度 (ndim):", arr.ndim)  # 输出: 2

    # todo 3.2、 数组形状 (shape): 数组的形状，是一个表示各维度大小的元组。

    '''
    区别与联系
       
        shape 是一个属性，用于获取或设置数组的形状。直接设置 shape 会修改原数组。
        reshape 是一个方法，用于返回一个新的数组，具有指定的形状，而不改变原数组。
    
    注意事项
       
        维度兼容性：
        
            使用 reshape 或设置 shape 时，新的形状必须与原数组的总元素数量一致。例如，一个包含 6 个元素的数组可以被重塑为 2x3 或 3x2，但不能重塑为 2x2。
     
        视图与副本：
        
            reshape 方法通常返回的是原数组的视图（view），这意味着改变新数组的数据也会影响原数组。然而，当内存布局不允许时，它可能返回一个副本（copy）。
    总结
        shape 是一个属性，用于获取或设置数组的形状。
        reshape 是一个方法，用于返回一个具有新形状的数组，而不改变原数组。
        使用这两个功能时，需要确保新形状与原数组的总元素数量一致。
    '''
    print("数组形状 (shape):", arr.shape)  # 输出: (2, 3)

    # 数组元素总数 (size): 数组中元素的总数。
    print("数组元素总数 (size):", arr.size)  # 输出: 6

    # 数组元素数据类型 (dtype): 数组中元素的数据类型。
    print("数组元素数据类型 (dtype):", arr.dtype)  # 输出: int64 (在某些系统上可能是 int32)

    # 数组元素字节大小 (itemsize): 数组中每个元素的字节大小。
    print("数组元素字节大小 (itemsize):", arr.itemsize)  # 输出: 8 (在某些系统上可能是 4)

    # 数组总字节大小 (nbytes): 数组中所有元素的总字节大小。
    print("数组总字节大小 (nbytes):", arr.nbytes)  # 输出: 48 (在某些系统上可能是 24)

    # todo 3.3、 数组转置 (T): 数组的转置。
    print("数组转置 (T):\n", arr.T)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 3.4、 逐个访问数组元素 (flat): 返回一个迭代器，可以逐个访问数组的元素。
    print("逐个访问数组元素 (flat):")
    for item in arr.flat:
        print(item, end=' ')
    print()

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 3.5、 创建复数数组并访问实部和虚部
    complex_arr = np.array([1 + 2j, 3 + 4j])

    # 复数数组实部 (real): 返回数组中元素的实部。
    print("复数数组实部 (real):", complex_arr.real)  # 输出: [1. 3.]

    # 复数数组虚部 (imag): 返回数组中元素的虚部。
    print("复数数组虚部 (imag):", complex_arr.imag)  # 输出: [2. 4.]

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 3.6、 ndarray.flags 返回 ndarray 数组的内存信息，比如 ndarray 数组的存储方式，以及是否是其他数组的副本等。

    ''' 
        C_CONTIGUOUS: True：表示数组是按行优先存储的。
        F_CONTIGUOUS: False：表示数组不是按列优先存储的。
        OWNDATA: True：表示数组拥有其数据的内存。
        WRITEABLE: True：表示数组是可写的。
        ALIGNED: True：表示数组中的数据在内存中是对齐的。
        WRITEBACKIFCOPY: False：表示数组不是临时副本，或者修改不会写回到原始数组。
    '''
    print(complex_arr.flags)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    #  todo 3.7、说一下视图
    # 1. 通过切片创建视图
    '''切片是创建视图数组最常见的方法之一。切片操作不会复制数据，而是创建一个共享相同数据存储的新数组
    arr[行索引，列索引] 这里可以用切片操作分别去数组的行列数'''
    arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

    # 通过切片创建视图数组
    sub_arr = arr[1:, 1:]

    # 打印原始数组和视图数组
    print("Original array:")
    print(arr)

    print("View array (sub_arr):")
    print(sub_arr)

    # 检查视图数组的 base 属性

    ''' 数组对象的 base 属性用于指示该数组是否是通过视图创建的。
        如果一个数组是从另一个数组的视图创建的，那么它的 base 属性会指向那个原始数组。
        反之，如果一个数组是独立创建的（不是视图），那么它的 base 属性通常为 None。
    '''
    print("Is sub_arr a view of arr?", sub_arr.base is arr)  # 输出: True

    # 2. 使用 view() 方法创建视图
    '''view() 方法可以创建一个新视图，且可以改变数据类型。'''

    # 使用 view() 方法创建视图数组
    view_arr = arr.view()

    # 打印原始数组和视图数组
    print("Original array:")
    print(arr)

    print("View array (view_arr):")
    print(view_arr)

    # 检查视图数组的 base 属性
    print("Is view_arr a view of arr?", view_arr.base is arr)  # 输出: True

    # 3. 使用高级索引创建视图
    '''高级索引（如布尔索引）通常会创建副本而不是视图，但在某些情况下可以通过花式索引创建视图。'''
    # 创建一个原始数组
    arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

    # 使用高级索引创建视图数组（注意：布尔索引通常会创建副本）
    sub_arr = arr[::2, ::2]

    # 打印原始数组和视图数组
    print("Original array:")
    print(arr)

    print("View array (sub_arr):")
    print(sub_arr)

    # 检查视图数组的 base 属性
    print("Is sub_arr a view of arr?", sub_arr.base is arr)  # 输出: True

    #  todo 3.8、复数
    """
    复数的定义

    复数是数学中的一种数，它由一个实数部分和一个虚数部分组成。复数通常表示为 a + bj 的形式，其中：

    - a 是实数部分。
    - b 是虚数部分。
    - j（在数学中通常用 i 表示，但在计算机科学和工程中常用 j）是虚数单位，满足 j^2 = -1。

    复数的表示

    一个复数可以表示为：

        z = a + bj

    例如，复数 3 + 4j 中，实数部分是 3，虚数部分是 4。

    复数的基本运算

    复数可以进行加法、减法、乘法和除法等运算。

    - 加法：
        (a + bj) + (c + dj) = (a + c) + (b + d)j

    - 减法：
        (a + bj) - (c + dj) = (a - c) + (b - d)j

    - 乘法：
        (a + bj) * (c + dj) = (ac - bd) + (ad + bc)j

    - 除法：
        (a + bj) / (c + dj) = ((a + bj) * (c - dj)) / (c^2 + d^2)
        其中，分母 c^2 + d^2 是 c + dj 的模平方。

    NumPy 中的复数

    在 NumPy 中，可以使用 dtype="complex" 来创建包含复数的数组。NumPy 中的复数类型通常是 complex64 或 complex128，分别表示 64 位和 128 位的复数。

    示例代码

    以下是一些使用 NumPy 操作复数的示例：

        import numpy as np

        # 创建包含复数的数组
        c = np.array([2, 4, 6, 8], dtype="complex")

        print("数组 c:", c)

        # 复数加法
        c1 = np.array([1+2j, 3+4j])
        c2 = np.array([5+6j, 7+8j])
        result_add = c1 + c2
        print("复数加法:", result_add)

        # 复数乘法
        result_mul = c1 * c2
        print("复数乘法:", result_mul)

    输出

        数组 c: [2.+0.j 4.+0.j 6.+0.j 8.+0.j]
        复数加法: [ 6. +8.j 10.+12.j]
        复数乘法: [-7.+16.j -11.+52.j]

    总结

    复数在数学和工程领域有广泛的应用，如信号处理、控制系统和量子力学等。NumPy 提供了对复数的支持，使得在计算和处理复数时更加方便和高效。通过指定 dtype="complex"，用户可以轻松创建和操作包含复数的数组。
    """

    c = np.array([2, 4, 6, 8], dtype="complex")
    print(c)

    # ndim查看数组维数
    arr = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 23]])
    print(arr.ndim)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # todo 3.9、 reshape 数组变维

    """
    数组的形状指的是多维数组的行数和列数。NumPy 模块提供 reshape() 函数可以改变多维数组行数和列数，从而达到数组变维的目的。因此数组变维即对数组形状的重塑，如图1所示：

        2 x 3 矩阵:
        1 2
        3 4
        5 6

        变维后的 3 x 2 矩阵:
        1 2 3
        4 5 6

    图1: reshape 函数数组变维

    reshape() 函数可以接受一个元组作为参数，用于指定了新数组的行数和列数，示例如下：


    输出结果:

        原数组: [[1 2]
                 [3 4]
                 [5 6]]

        新数组: [[1 2 3]
                 [4 5 6]]

     元素总数不变: 使用 reshape 函数时，新形状的总元素数量必须与原数组相同。例如，一个包含 6 个元素的一维数组可以变形为 2x3 或 3x2 的二维数组，但不能变形为 2x2 的二维数组。

    自动推断: 可以使用 -1 让 NumPy 自动推断某一维度的大小。
    内存视图: reshape 返回的是原数组的视图（view），并不是数据的副本。因此，改变新数组的元素值也会改变原数组。

    """

    e = np.array([[1, 2], [3, 4], [5, 6]])
    print("\n原数组:\n", e)
    e = e.reshape(2, -1)  # 这里 -1 表示自动计算列数
    print("\n新数组:\n", e)


def main():
    numpy_create_array()
    # numpy_type()
    # numpy_attribute()


if __name__ == '__main__':
    main()
